package lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by wangzhitao on 2021/12/22
 **/
public class ReentrantLockThread {
    public void test() {
        ReentrantLockFairRunnable runnable = new ReentrantLockFairRunnable();
        new Thread(runnable, "小王").start();
        new Thread(runnable, "小明").start();
        new Thread(runnable, "小罗").start();
        new Thread(runnable, "小李").start();
    }
}

class NoReentrantLockRunnable implements Runnable {
    final Lock lock = new ReentrantLock();

    @Override
    public void run() {
        study();
    }

    private void study() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+":我正在学习");
        }
    }
}

class ReentrantLockRunnable implements Runnable {
    final Lock lock = new ReentrantLock();

    @Override
    public void run() {
        study();
    }

    private void study() {
        lock.lock();
        try {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()+":我正在学习");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
}

class ReentrantTryLockRunnable implements Runnable {
    final Lock lock = new ReentrantLock();

    @Override
    public void run() {
        study();
    }

    private void study() {
        boolean flag = lock.tryLock();
        if (flag) {
            try {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName()+":我正在学习");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        } else {
            System.out.println(Thread.currentThread().getName()+":我没拿到锁，那我去看电视了");
        }
    }
}

class ReentrantTryLockDurationRunnable implements Runnable {
    final Lock lock = new ReentrantLock();

    @Override
    public void run() {
        study();
    }

    private void study() {
        try {
            boolean flag = lock.tryLock(5000, TimeUnit.MILLISECONDS);
            if (flag) {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + ":我正在学习");
                }
            } else {
                System.out.println(Thread.currentThread().getName() + ":我没拿到锁，那我去看电视了");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

class ReentrantLockFairRunnable implements Runnable {
    final Lock lock = new ReentrantLock(true); // true表示公平锁，false表示非公平锁，默认是false

    @Override
    public void run() {
        study();
    }

    private void study() {
        for (int i = 0; i < 2; i++) {
            try {
                lock.lock();
                System.out.println(Thread.currentThread().getName()+":我正在学习");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

    }
}